from google.colab import drive
drive.mount('/content/drive/')
Mounted at /content/drive/
from tqdm.notebook import trange, tqdm
from IPython.display import Image, display, Markdown, clear_output
from zipfile import ZipFile
import os
import cv2
import pandas as pd
import numpy as np
zip_dir_loc='/content/drive/MyDrive/face detection of cast/Part 2 - training images/training_images'
The names of the files
raw_img_file_names = [os.path.join(zip_dir_loc,i) for i in os.listdir(zip_dir_loc)]
raw_img_file_names[:5]
['/content/drive/MyDrive/face detection of cast/Part 2 - training images/training_images/real_00158.jpg', '/content/drive/MyDrive/face detection of cast/Part 2 - training images/training_images/real_00098.jpg', '/content/drive/MyDrive/face detection of cast/Part 2 - training images/training_images/real_00079.jpg', '/content/drive/MyDrive/face detection of cast/Part 2 - training images/training_images/real_00077.jpg', '/content/drive/MyDrive/face detection of cast/Part 2 - training images/training_images/real_00122.jpg']
Reading images
img_list = []
for imgs in tqdm(raw_img_file_names):
tst_img = cv2.imread(imgs)
img_list.append(tst_img)
img_list = np.array(img_list)
display(Markdown(f"#### {img_list.shape}"))
Viewing images
from google.colab.patches import cv2_imshow
for i in img_list[:3,]:
cv2_imshow(cv2.resize(i,(224,224)))
Bounding boxe function
def Bounding_box(df,fname,title=""):
tst_img = cv2.imread(fname)
temp_df = df[df['Image_Name'] == fname]
rect_img = []
for rows in temp_df.index:
x = df['x'][rows]
y = df['y'][rows]
w = df['w'][rows]
h = df['h'][rows]
cv2.rectangle(tst_img,(x,y),(x+w,y+h),(255,0,0),2)
cv2.putText(tst_img, title, (int((x+w)*0.75),y-3),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255))
cv2_imshow(tst_img)
return
Defining a function to read images and resize them
def show_face(img_list,scale=1.0):
for imgs in img_list:
img = cv2.imread(imgs)
img_w = int(img.shape[1]*scale)
img_h = int(img.shape[0]*scale)
img = cv2.resize(img,(img_w,img_h))
display(Markdown(f"#### {imgs}"))
cv2_imshow(img)
return
Downloading the HAAR Model
!wget https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml
--2021-12-15 14:16:05-- https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_default.xml Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ... Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 930127 (908K) [text/plain] Saving to: ‘haarcascade_frontalface_default.xml’ haarcascade_frontal 100%[===================>] 908.33K --.-KB/s in 0.04s 2021-12-15 14:16:05 (19.8 MB/s) - ‘haarcascade_frontalface_default.xml’ saved [930127/930127]
haar_img_box_df = pd.DataFrame(columns=['x','y','w','h','Total_Faces','Image_Name'])
haar_img_box_df
| x | y | w | h | Total_Faces | Image_Name |
|---|
Detecting Faces using HAAR Model
raw_img_file_names[2]
'/content/drive/MyDrive/face detection of cast/Part 2 - training images/training_images/real_00079.jpg'
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
test_img = cv2.imread(raw_img_file_names[2])
grey = cv2.cvtColor(test_img, cv2.COLOR_BGR2GRAY)
# Detect faces
faces = face_cascade.detectMultiScale(grey,1.1,4)
# Draw rectangle around the faces
for (x, y, w, h) in faces:
cv2.rectangle(test_img, (x, y), (x+w, y+h), (255, 0, 0), 2)
cv2.putText(test_img, "HaarCascadeClassifier", (int((x+w)*0.75),y-3),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255))
# Display the output
display(Markdown(f"### Bounding Box parameters are `x`:{x}, `y`:{y}, `width`:{w}, `height`:{h}"))
cv2_imshow(test_img)
x:40, y:138, width:408, height:408¶Detecting faces for all the images
%%time
haar_undetected_images = []
haar_detected_images = []
for imgs, fnames in tqdm(zip(img_list,raw_img_file_names)):
gray = cv2.cvtColor(imgs,cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray,1.1,4)
if len(faces) == 0:
haar_undetected_images.append(fnames)
temp_dict = {'x':0,
'y':0,
'w':-1,
'h':-1,
'Total_Faces':0,
'Image_Name':fnames}
else:
haar_detected_images.append(fnames)
for (x,y,w,h) in faces:
temp_dict = {'x':x,
'y':y,
'w':w,
'h':h,
'Total_Faces':len(faces),
'Image_Name':fnames}
haar_img_box_df = haar_img_box_df.append(temp_dict,ignore_index=True)
display(Markdown(f"#### Detected faces for {len(haar_detected_images)} images"))
display(Markdown(f"#### Failed to detect faces for {len(haar_undetected_images)} images"))
haar_img_box_df
| x | y | w | h | Total_Faces | Image_Name | |
|---|---|---|---|---|---|---|
| 0 | 44 | 102 | 472 | 472 | 1 | /content/drive/MyDrive/face detection of cast/... |
| 1 | 40 | 138 | 408 | 408 | 1 | /content/drive/MyDrive/face detection of cast/... |
| 2 | 30 | 71 | 508 | 508 | 1 | /content/drive/MyDrive/face detection of cast/... |
| 3 | 167 | 139 | 367 | 367 | 1 | /content/drive/MyDrive/face detection of cast/... |
| 4 | 42 | 87 | 484 | 484 | 1 | /content/drive/MyDrive/face detection of cast/... |
| ... | ... | ... | ... | ... | ... | ... |
| 1006 | 28 | 60 | 501 | 501 | 1 | /content/drive/MyDrive/face detection of cast/... |
| 1007 | 92 | 179 | 383 | 383 | 3 | /content/drive/MyDrive/face detection of cast/... |
| 1008 | 4 | 375 | 101 | 101 | 3 | /content/drive/MyDrive/face detection of cast/... |
| 1009 | 13 | 562 | 28 | 28 | 3 | /content/drive/MyDrive/face detection of cast/... |
| 1010 | 61 | 69 | 477 | 477 | 1 | /content/drive/MyDrive/face detection of cast/... |
1011 rows × 6 columns
Out of a total of 1091 images, the HAAR was able to detect only 1011 images with one or more faces correctly.
haar_img_box_df[haar_img_box_df['Total_Faces'] > 1]
| x | y | w | h | Total_Faces | Image_Name | |
|---|---|---|---|---|---|---|
| 10 | 17 | 84 | 466 | 466 | 2 | /content/drive/MyDrive/face detection of cast/... |
| 11 | 121 | 358 | 130 | 130 | 2 | /content/drive/MyDrive/face detection of cast/... |
| 23 | 197 | 95 | 388 | 388 | 2 | /content/drive/MyDrive/face detection of cast/... |
| 24 | 29 | 196 | 160 | 160 | 2 | /content/drive/MyDrive/face detection of cast/... |
| 50 | 28 | 1 | 55 | 55 | 2 | /content/drive/MyDrive/face detection of cast/... |
| ... | ... | ... | ... | ... | ... | ... |
| 973 | 201 | 301 | 106 | 106 | 2 | /content/drive/MyDrive/face detection of cast/... |
| 974 | 496 | 475 | 70 | 70 | 2 | /content/drive/MyDrive/face detection of cast/... |
| 1007 | 92 | 179 | 383 | 383 | 3 | /content/drive/MyDrive/face detection of cast/... |
| 1008 | 4 | 375 | 101 | 101 | 3 | /content/drive/MyDrive/face detection of cast/... |
| 1009 | 13 | 562 | 28 | 28 | 3 | /content/drive/MyDrive/face detection of cast/... |
156 rows × 6 columns
There are 156 images which have more than one face.
Viewing samples of correctly detected faces using the HAAR Model
display(Markdown("### Correctly detected face"))
Bounding_box(haar_img_box_df,"/content/drive/MyDrive/face detection of cast/Part 2 - training images/training_images/real_00022.jpg",title="Haar")
display(Markdown("### Correctly detected face"))
Bounding_box(haar_img_box_df,"/content/drive/MyDrive/face detection of cast/Part 2 - training images/training_images/real_01009.jpg",title="Haar")
Displaying all the faces that were not detected by HAAR Model
haar_set = set(haar_undetected_images)
show_face(haar_set,0.3)
Observation:
There are images where a face could not be detected due to:
Face partailly covered
Face zoomed such that it crops part of the face
Poor illumination or partially lit surfaces on the face
Tilted face
Side face